package org.rpgmapper.skirmish;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.rpgmapper.bo.Bonus;
import org.rpgmapper.bo.BonusType;
import org.rpgmapper.bo.Character;
import org.rpgmapper.comparator.CharacterComparator;
import org.rpgmapper.database.RPGMapperOpenHelper;

import android.content.Context;
import android.text.Html;
import android.text.Spanned;
import org.rpgmapper.manager.CharacterSelectionListener;

public class SkirmishManager implements CharacterSelectionListener {

    private static SkirmishManager instance;
    private List<Character> characters = new ArrayList<Character>();
    private List<Bonus> characterBonus = new ArrayList<Bonus>();
    private List<Bonus> monsterBonus = new ArrayList<Bonus>();
    private Character selectedCharacter;
    private int roundNumber = 1;
    private int currentCharacterIndex = 0;
    private SkirmishListener skirmishListener;

    public static SkirmishManager getInstance() {
        if (null == instance) {
            instance = new SkirmishManager();
        }
        return instance;
    }

    private SkirmishManager() {
    }

    /*
     *  Permet de passer au prochain personnage.
     *  Si le round se termine, on d�clenche le nextRound()
     */
    public void nextCharacter() {
        boolean next = false;
        this.currentCharacterIndex++;
        if (this.currentCharacterIndex == this.characters.size()) {
            this.currentCharacterIndex = 0;
            next = true;
        }
        if (this.skirmishListener != null) {
            this.skirmishListener.onChangeCharacter(this.getCharacter());
        }
        // si on a passé tous les characters
        // alors on refait un round
        if (next) {
            this.nextRound();
        }
    }

    /*
     * Permet de passer au round suivant
     * On notifie l'appelant pour qu'il puisse faire des choses
     */
    public void nextRound() {
        this.currentCharacterIndex = 0;
        this.roundNumber++;
        for (Bonus b : this.characterBonus) {
            b.decDuration();
        }
        for (Bonus b : this.monsterBonus) {
            b.decDuration();
        }
        if (this.skirmishListener != null) {
            this.skirmishListener.onChangeRound(this.roundNumber);
        }
    }

    public void beginSkirmish() {
        this.characterBonus.clear();
        this.monsterBonus.clear();
        this.characters.clear();
        this.roundNumber = 1;
        this.currentCharacterIndex = 0;
        if (this.skirmishListener != null) {
            this.skirmishListener.onBeginSkirmish();
        }
    }

    public void endSkirmish() {
        this.characterBonus.clear();
        this.monsterBonus.clear();
        this.characters.clear();
        this.roundNumber = 1;
        this.currentCharacterIndex = 0;
        if (this.skirmishListener != null) {
            this.skirmishListener.onEndSkirmish();
        }
    }

    public void showCharacterInfo() {
        if (this.skirmishListener != null && selectedCharacter != null) {
            this.skirmishListener.onShowCharacterInfo(selectedCharacter);
        }
    }

    public Spanned getCharactersAsText() {
        String str = "<b>" + roundNumber + "</b> |";
        int i = 0;
        if (this.characters != null) {
            for (Character c : this.characters) {
                if (i == this.currentCharacterIndex) {
                    str += " <b><u>" + c.getName() + "</u></b> >";
                } else {
                    str += " " + c.getName() + " >";
                }
                i++;
            }
            if (i > 0) {
                str = str.substring(0, str.length() - 2);
            }
        }
        return Html.fromHtml(str);
    }

    public Spanned getCharactersBonusAsText() {
        String characterStr = "";
        if (this.characterBonus != null) {
            for (Bonus b : this.characterBonus) {
                characterStr += b.getEffect() + " (" + b.getDurationBeforeEnd() + ")" + " | ";
            }
            if (this.characterBonus.size() == 0) {
                characterStr += "-";
            } else {
                characterStr = characterStr.substring(0, characterStr.length() - 3);
            }
        } else {
            characterStr += "-";
        }

        return Html.fromHtml(characterStr);
    }

    public Spanned getMonstersBonusAsText() {
        String monsterStr = "";
        if (this.monsterBonus != null) {
            for (Bonus b : this.monsterBonus) {
                monsterStr += b.getEffect() + " (" + b.getDurationBeforeEnd() + ")" + " | ";
            }
            if (this.monsterBonus.size() == 0) {
                monsterStr += "-";
            } else {
                monsterStr = monsterStr.substring(0, monsterStr.length() - 3);
            }
        } else {
            monsterStr += "-";
        }

        return Html.fromHtml(monsterStr);
    }
    private OnBonusEndListener onBonusEndListener = new OnBonusEndListener() {

        public void onBonusEnd(Bonus bonus) {
            if (bonus.getType().equals(BonusType.CHARACTER)) {
                SkirmishManager.this.characterBonus.remove(bonus);
            } else {
                SkirmishManager.this.monsterBonus.remove(bonus);
            }

            if (skirmishListener != null) {
                skirmishListener.onBonusEnd(bonus);
            }
        }
    };

    public void addBonus(Bonus bonus) {
        if (this.characterBonus == null) {
            this.characterBonus = new ArrayList<Bonus>();
        }
        if (this.monsterBonus == null) {
            this.monsterBonus = new ArrayList<Bonus>();
        }
        if (bonus.getType().equals(BonusType.CHARACTER)) {
            this.characterBonus.add(bonus);
        } else {
            this.monsterBonus.add(bonus);
        }
        bonus.setOnBonusEndListener(onBonusEndListener);

        if (this.skirmishListener != null) {
            this.skirmishListener.onAddBonus(bonus);
        }
    }

    public List<Character> getCharacters() {
        return characters;
    }

    public void setCharacters(List<Character> characters) {
        this.characters = characters;
        Collections.sort(this.characters, new CharacterComparator());
        if (this.skirmishListener != null) {
            for (Character character : characters) {
                this.skirmishListener.onAddCharacter(character);
            }
        }
    }

    public void wantToAddCharacter() {
        if (this.skirmishListener != null) {
            this.skirmishListener.onWantToAddCharacter();
        }
    }

    public void addCharacter(Character character) {
        if (this.characters == null) {
            this.characters = new ArrayList<Character>();
        }        
        character.setId(System.currentTimeMillis());
        this.characters.add(character);
        Collections.sort(this.characters, new CharacterComparator());
//        for (Character c : this.characters) {
//            System.err.println(c.toString());
//        }
        if (this.skirmishListener != null) {
            this.skirmishListener.onAddCharacter(character);
        }
    }
    
    public void removeCharacter(Character character) {
        if(character == selectedCharacter){
            selectedCharacter = null;
        }
       
        this.characters.remove(character);
        Collections.sort(this.characters, new CharacterComparator());
     
        if (this.skirmishListener != null) {
            this.skirmishListener.onRemoveCharacter(character);
        }
    }

    public void refreshCharacters(Context context) {
        RPGMapperOpenHelper helper = new RPGMapperOpenHelper(context);
        if (this.characters != null) {
            List<Character> newList = new ArrayList<Character>();
            for (Character character : this.characters) {
                character = helper.getCharacterById(character.getId());
                System.err.println(character.getName() + " : " + character.getSide());
                newList.add(character);
            }
            this.characters = newList;
            for (Character character : newList) {
                System.err.println(character.toString());
            }
            Collections.sort(this.characters, new CharacterComparator());
        }
    }

    public int getRoundNumber() {
        return roundNumber;
    }

    public void setRoundNumber(int roundNumber) {
        this.roundNumber = roundNumber;
    }

    public SkirmishListener getSkirmishListener() {
        return skirmishListener;
    }

    public void setSkirmishListener(SkirmishListener skirmishListener) {
        this.skirmishListener = skirmishListener;
    }

    public Character getCharacter() {
        if (this.characters != null && this.currentCharacterIndex < this.characters.size()) {
            return this.characters.get(this.currentCharacterIndex);
        } else {
            return null;
        }
    }

    public Character getSelectedCharacter() {
        return selectedCharacter;
    }

    public void onCharacterSelect(String string) {
        if (this.characters != null) {
            for (Character character : characters) {
                if ((character.getId() + "").equals(string)) {
                    selectedCharacter = character;
                    return;
                }
            }
        }
    }
}
